package com.birdcage.goldminer.gameobjects;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.math.Vector2;
import com.birdcage.gamemanagers.GameObject;
import com.birdcage.gamemanagers.ResourceManager;
import com.birdcage.gamemanagers.GameObject.EGameObjectType;
import com.birdcage.goldminer.Level;

public class Player extends GameObject {


    private Level m_level;

    private final Vector2 m_rotateOrigin = new Vector2(400, 400);
    private final Vector2 m_curPos = m_rotateOrigin;
    private float m_rotateRadius = 10.0f;
    private float m_maxDegree = 80;
    private float m_rotateSpeed = 10;
    private float m_currentDegree = 0;
    private int m_curRotateDirFactor = 1;
    private float m_ejectSpeed = 500.f;
    private float m_ejectLength = 250;

    private final String m_stateIdle = "Idle";
    private final String m_stateEject = "Eject";
    private final String m_stateReturn = "Return";

    public Player(Level level) {
        super(EGameObjectType.eGOT_Player, 0);

        Gdx.app.log("Player", "Player");

        m_level = level;

        Texture hookImage = new Texture(ResourceManager.GetInstance().LoadResource("hook.png", true));
        hookImage.setWrap(TextureWrap.ClampToEdge, TextureWrap.ClampToEdge);
        AddRenderUnit(hookImage, -50, -50);

        try
        {            
            GetFSM().AddState(m_stateIdle, this);
            GetFSM().AddState(m_stateEject, this);
            GetFSM().AddState(m_stateReturn, this);
            GetFSM().InitState(m_stateIdle);
        } catch (SecurityException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        SetWorldPos(m_rotateOrigin);
    }  

    /*
     * FSMState call-back methods.
     */
    private void Idle_Enter() {
        Gdx.app.log("Player", "Idle_Enter"); 

        m_physElem.SetVelocity(0f);
        SetWorldPos(m_rotateOrigin);
    }

    private void Idle_Update() {
        Gdx.app.log("Player", "Idle_Update");

        GetFSM().SwitchState(Gdx.input.isTouched(), m_stateEject);


        if (m_currentDegree > m_maxDegree || m_currentDegree < -m_maxDegree)
        {
            m_curRotateDirFactor *= -1;
        }
        m_currentDegree += m_rotateSpeed * m_curRotateDirFactor;
        
        SetRotation(m_currentDegree);
    }

    private void Idle_Exit() {
        Gdx.app.log("Player", "Idle_Exit");
    }

    private void Eject_Enter() {
        Gdx.app.log("Player", "Eject_Enter");
        
        m_physElem.SetVelocity(m_ejectSpeed * 2);
        Vector2 currentDir = new Vector2(0, -1);
        currentDir.rotate(m_currentDegree);
        m_physElem.SetDir(currentDir);
    }

    private void Eject_Update() {
        Gdx.app.log("Player", "Eject_Update");
        //check collision
        Vector2 deltaVec = new Vector2();
        deltaVec.set(GetWorldPos());
        deltaVec.sub(m_rotateOrigin);
        boolean outOfRange = (deltaVec.len() > m_ejectLength);
        GetFSM().SwitchState(outOfRange, m_stateReturn);
    }

    private void Eject_Exit() {
        Gdx.app.log("Player", "Eject_Exit");
    }

    private void Return_Enter() {
        Gdx.app.log("Player", "Return_Enter");
        Vector2 backDir = new Vector2();
        backDir.set(m_physElem.GetDir());
        backDir.mul(-1);
        m_physElem.SetDir(backDir);
        m_physElem.SetVelocity(m_ejectSpeed);      
    }

    private void Return_Update() {
        Gdx.app.log("Player", "Return_Update");

        ///Try to switch
        Vector2 deltaVec = new Vector2();
        deltaVec.set(GetWorldPos());
        deltaVec.sub(m_rotateOrigin);
        boolean outOfRange = (deltaVec.len() <= m_rotateRadius);
        GetFSM().SwitchState(outOfRange, m_stateIdle);
    }

    private void Return_Exit() {
        Gdx.app.log("Player", "Return_Exit");
    }
}
